#include "networksd.h"

#include "../core/core.h"

#include <QTabWidget>
#include <QWidget>
#include <QGroupBox>
#include <QSpinBox>
#include <QLineEdit>
#include <QCheckBox>
#include <QLabel>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QDebug>

#include "../ui/openlineedit.h"


class NetworkSD::NetworkSDPrivate {
public:
	NetworkSDPrivate();
	~NetworkSDPrivate();

	QTabWidget *m_pTab;

	QSpinBox *m_pListeningPort;

	OpenLineEdit *m_pServerKey;
	QCheckBox *m_pDefaultKey;

	OpenLineEdit *m_pServerCert;
	QCheckBox *m_pDefaultCert;

	OpenLineEdit *m_pServerCa;
	QCheckBox *m_pDefaultCa;

	bool m_spinboxChanged;
	bool m_certBoxChanged;
	bool m_keyBoxChanged;
	bool m_caBoxChanged;
};

NetworkSD::NetworkSDPrivate::NetworkSDPrivate(){
	m_pTab = NULL;

	m_spinboxChanged = false;
	m_keyBoxChanged = false;
	m_certBoxChanged = false;
	m_caBoxChanged = false;
}

NetworkSD::NetworkSDPrivate::~NetworkSDPrivate(){
	delete m_pTab;
}

//end of d-class part
//------------------------------------------------------------------------------
NetworkSD::NetworkSD() :
	QObject(0),
	d(new NetworkSDPrivate())
{
}

NetworkSD::~NetworkSD(){
	delete d;
}

QString NetworkSD::category() const {
	return tr("Sieć");
}

QIcon NetworkSD::categoryIcon() const {
	return QIcon(":/settings/res/preferences-system-network.png");
}

QTabWidget* NetworkSD::createPages(){
	if( d->m_pTab )
		return d->m_pTab;



	d->m_pTab = new QTabWidget();

	QWidget *general = new QWidget( d->m_pTab );
	d->m_pTab->addTab( general, tr("Ogólne") );



	QGroupBox *box = new QGroupBox( tr("Ogólne"), general );
	QFormLayout *formBox = new QFormLayout( box );

	d->m_pListeningPort = new QSpinBox( box );
	d->m_pListeningPort->setRange(0, 65535);
	d->m_pListeningPort->setValue(
			Core::instance()->settings()->value( "general/network/incomingPort",
												 QVariant(443) )
			.toInt() );
	d->m_pListeningPort->setToolTip( tr("Domyślny port: 443") );
	connect( d->m_pListeningPort, SIGNAL(valueChanged(int)),
			 this, SLOT(spinboxChanged(int)) );

	formBox->addRow( tr("Port nasłuchu:"), d->m_pListeningPort );


	box->setLayout( formBox );

	//SSL
	//----------
	QGroupBox *box2 = new QGroupBox( tr("SSL"), general );
	QGridLayout *gridForm = new QGridLayout( box2 );

	d->m_pServerKey = new OpenLineEdit( box2 );
	d->m_pServerKey->setText(
			Core::instance()->settings()->value( "general/network/SSLKey",
												 QVariant() )
			.toString() );
	d->m_pServerKey->setModified( false );
	d->m_pServerKey->setToolTip( tr("Klucz prywatny serwera,\n"
										"jeśli pusty używamy domyślnego") );

	d->m_pDefaultKey = new QCheckBox( tr("Domyślny"), box2 );
	d->m_pDefaultKey->setChecked(
			Core::instance()->settings()->value("general/network/SSLKeyDefault",
												 QVariant(true) )
			.toBool() );
	if( d->m_pDefaultKey->isChecked() )
		d->m_pServerKey->setEnabled( false );

	connect( d->m_pDefaultKey, SIGNAL(stateChanged(int)),
			 this, SLOT(keyCheckBoxChanged(int)) );



	d->m_pServerCert = new OpenLineEdit( box2 );
	d->m_pServerCert->setText(
			Core::instance()->settings()->value( "general/network/SSLCert",
												 QVariant() )
			.toString() );
	d->m_pServerCert->setModified( false );
	d->m_pServerCert->setToolTip( tr("Certyfikat serwera,\n"
									 "jeśli pusty używamy domyślnego") );

	d->m_pDefaultCert = new QCheckBox( tr("Domyślny"), box2 );
	d->m_pDefaultCert->setChecked(
		Core::instance()->settings()->value("general/network/SSLCertDefault",
											QVariant(true) )
		.toBool() );
	if( d->m_pDefaultCert->isChecked() )
		d->m_pServerCert->setEnabled( false );

	connect( d->m_pDefaultCert, SIGNAL(stateChanged(int)),
			 this, SLOT(certCheckBoxChanged(int)) );



	d->m_pServerCa = new OpenLineEdit( box2 );
	d->m_pServerCa->setText(
			Core::instance()->settings()->value( "general/network/SSLCertCA",
												 QVariant() )
			.toString() );
	d->m_pServerCa->setModified( false );
	d->m_pServerCa->setToolTip( tr("Certyfikat CA dla certyfikatu serwera,\n"
								   "jeśli pusty uznajemy że jest z "
								   "podpisem własnym") );

	d->m_pDefaultCa = new QCheckBox( tr("Podpis własny"), box2 );
	d->m_pDefaultCa->setChecked(
		Core::instance()->settings()->value("general/network/SSLCertCADefault",
											QVariant(true) )
		.toBool() );
	if( d->m_pDefaultCa->isChecked() )
		d->m_pServerCa->setEnabled( false );

	connect( d->m_pDefaultCa, SIGNAL(stateChanged(int)),
			 this, SLOT(caCheckBoxChanged(int)) );

	gridForm->addWidget( new QLabel( tr("Klucz prywatny:"), box2), 0, 0 );
	gridForm->addWidget( d->m_pServerKey, 0, 1 );
	gridForm->addWidget( d->m_pDefaultKey, 0, 2 );
	gridForm->addWidget( new QLabel( tr("Certyfikat:"), box2), 1, 0 );
	gridForm->addWidget( d->m_pServerCert, 1, 1 );
	gridForm->addWidget( d->m_pDefaultCert, 1, 2 );
	gridForm->addWidget( new QLabel( tr("Certyfikat CA:"), box2), 2, 0 );
	gridForm->addWidget( d->m_pServerCa, 2, 1 );
	gridForm->addWidget( d->m_pDefaultCa, 2, 2 );


	QSpacerItem *spacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum,
										   QSizePolicy::MinimumExpanding );
	gridForm->addItem( spacer, 100, 0 );
	box2->setLayout( gridForm );


	general->setLayout( new QVBoxLayout( general ) );

	general->layout()->addWidget( box );
	general->layout()->addWidget( box2 );

	return d->m_pTab;
}

void NetworkSD::spinboxChanged(int){
	d->m_spinboxChanged = true;
}

void NetworkSD::certCheckBoxChanged(int state){
	if( Qt::Checked == state ){
		d->m_pServerCert->setEnabled( false );
	}else{
		d->m_pServerCert->setEnabled( true );
	}
	d->m_certBoxChanged = true;
}

void NetworkSD::keyCheckBoxChanged(int state){
	if( Qt::Checked == state ){
		d->m_pServerKey->setEnabled( false );
	}else{
		d->m_pServerKey->setEnabled( true );
	}
	d->m_keyBoxChanged = true;
}

void NetworkSD::caCheckBoxChanged(int state){
	if( Qt::Checked == state ){
		d->m_pServerCa->setEnabled( false );
	}else{
		d->m_pServerCa->setEnabled( true );
	}
	d->m_caBoxChanged = true;
}

void NetworkSD::save(){
	if( d->m_spinboxChanged ){
		Core::instance()->settings()->setValue( "general/network/incomingPort",
												d->m_pListeningPort->value() );
		d->m_spinboxChanged = false;
	}

	if( d->m_pServerKey->isModified() ){
		if( d->m_pServerKey->isEmpty() ){
			Core::instance()->settings()->setValue(
					"general/network/SSLKeyDefault", true );
			d->m_pDefaultKey->setChecked( true );
			d->m_keyBoxChanged = false;
		}

		Core::instance()->settings()->setValue( "general/network/SSLKey",
												d->m_pServerKey->text() );

		d->m_pServerKey->setModified( false );
	}

	if( d->m_pServerCert->isModified() ){
		if( d->m_pServerCert->isEmpty() ){
			Core::instance()->settings()->setValue(
					"general/network/SSLCertDefault", true );
			d->m_pDefaultCert->setChecked( true );
			d->m_certBoxChanged = false;
		}

		Core::instance()->settings()->setValue( "general/network/SSLCert",
												d->m_pServerCert->text() );

		d->m_pServerCert->setModified( false );
	}

	if( d->m_pServerCa->isModified() ){
		if( d->m_pServerCa->isEmpty() ){
			Core::instance()->settings()->setValue(
					"general/network/SSLCertCADefault", true );
			d->m_pDefaultCa->setChecked( true );
			d->m_caBoxChanged = false;
		}

		Core::instance()->settings()->setValue( "general/network/SSLCertCA",
												d->m_pServerCa->text() );

		d->m_pServerCa->setModified( false );
	}

	if( d->m_keyBoxChanged ){
		Core::instance()->settings()->setValue(
				"general/network/SSLKeyDefault",
				d->m_pDefaultKey->isChecked()
		);

		d->m_keyBoxChanged = false;
	}

	if( d->m_certBoxChanged ){
		Core::instance()->settings()->setValue(
				"general/network/SSLCertDefault",
				d->m_pDefaultCert->isChecked()
		);

		d->m_certBoxChanged = false;
	}

	if( d->m_caBoxChanged ){
		Core::instance()->settings()->setValue(
				"general/network/SSLCertCADefault",
				d->m_pDefaultCa->isChecked()
		);

		d->m_caBoxChanged = false;
	}
}

void NetworkSD::reset(){
	if( d->m_spinboxChanged ){
		d->m_pListeningPort->setValue(
				Core::instance()->settings()->value(
						"general/network/incomingPort",
						QVariant(443) ).toInt() );

		d->m_spinboxChanged = false;
	}

	if( d->m_pServerKey->isModified() ){
		d->m_pServerKey->setText(
				Core::instance()->settings()->value( "general/network/SSLKey",
													 QVariant() )
				.toString() );
		d->m_pServerKey->setModified( false );
	}

	if( d->m_pServerCert->isModified() ){
		d->m_pServerCert->setText(
				Core::instance()->settings()->value( "general/network/SSLCert",
													 QVariant() )
				.toString() );
		d->m_pServerCert->setModified( false );
	}

	if( d->m_pServerCa->isModified() ){
		d->m_pServerCa->setText(
				Core::instance()->settings()->value("general/network/SSLCertCA",
													QVariant() )
				.toString() );
		d->m_pServerCa->setModified( false );
	}

	if( d->m_keyBoxChanged ){
		d->m_pDefaultKey->setChecked(
				Core::instance()->settings()->value(
						"general/network/SSLKeyDefault",
						QVariant(true) ).toBool() );

		d->m_keyBoxChanged = false;
	}

	if( d->m_certBoxChanged ){
		d->m_pDefaultCert->setChecked(
			Core::instance()->settings()->value(
					"general/network/SSLCertDefault",
					QVariant(true) ).toBool() );

		d->m_certBoxChanged = false;
	}

	if( d->m_caBoxChanged ){
		d->m_pDefaultCa->setChecked(
			Core::instance()->settings()->value(
					"general/network/SSLCertCADefault",
					QVariant(true) ).toBool() );

		d->m_caBoxChanged = false;
	}

}
